package com.mbl.base.core.common.controller;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mbl.base.core.common.dto.MblResult;
import com.mbl.base.core.common.page.LayuiPageFactory;
import com.mbl.base.core.utils.UtilClass;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.URLDecoder;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

public class BaseController<T, E extends IService<T>> {
    public final String LOG_NAME = "模块名称";
    public String PREFIX = "/modular";
    @Autowired
    private E iService;

    public E getService() {
        return (E) iService;
    }

    @ApiImplicitParams({
            @ApiImplicitParam(name = "limit", value = "数据条数"),
            @ApiImplicitParam(name = "page", value = "页码"),
            @ApiImplicitParam(name = "startTime", value = "开始时间"),
            @ApiImplicitParam(name = "endTime", value = "结束时间"),
            @ApiImplicitParam(name = "condtion", value = "请求参数Array(col:列名，rule：比对规则(eq,like,ge,le),val：比对值)")
    })
    @PostMapping(value = "/list")
    public MblResult list(@RequestParam(value = "condition", required = false) String condition) throws UnsupportedEncodingException {
        if(StringUtils.isBlank(condition)) {
            condition = "";
        }
        condition = URLDecoder.decode(condition, "UTF-8");
        Page page = LayuiPageFactory.defaultPage();//获取分页参数
        QueryWrapper<T> queryWrapper = new QueryWrapper();
        queryWrapper.orderByDesc("update_time");
        machiningList(queryWrapper, condition);
        IPage<T> page1 = iService.page(page, queryWrapper);
        machiningListResult(page1);
        return MblResult.success(page1);
    }
    public void machiningListResult(IPage<T> page1) {
    }
    public void machiningList(QueryWrapper<T> queryWrapper, String condition) {
        if(StringUtils.isNotBlank(condition) && JSONUtil.isJsonArray(condition)){
            final JSONArray objects = JSON.parseArray(condition);
            objects.forEach(obj -> {
                JSONObject jsonObject = (JSONObject) obj;
                final String rule = jsonObject.getString("rule");
                switch (rule) {
                    case "eq":queryWrapper.eq(jsonObject.getString("col"),jsonObject.getString("val"));break;
                    case "like":queryWrapper.like(jsonObject.getString("col"),jsonObject.getString("val"));;break;
                    case "ge":queryWrapper.ge(jsonObject.getString("col"),jsonObject.getString("val"));;break;
                    case "le":queryWrapper.le(jsonObject.getString("col"),jsonObject.getString("val"));;break;
                }
            });
        }
    }
    @PostMapping(value = "/add")
    public MblResult add(@RequestBody T obj) {
        machiningAdd(obj);
        this.iService.saveOrUpdate(obj);
        return MblResult.success();
    }
    public void machiningAdd(T obj) {
    }
    @PostMapping(value = "/edit")
    public MblResult edit(@RequestBody T obj) {
        machiningEdit(obj);
        this.iService.updateById(obj);
        return MblResult.success();
    }

    public void machiningEdit(T obj) {
    }

    @PostMapping(value = "/remove")
    public MblResult remove(@RequestParam Long id) {
        this.iService.removeById(id);
        return MblResult.success();
    }

    @PostMapping(value = "/view")
    public MblResult view(@RequestParam Long id) {
        final T obj = this.iService.getById(id);
        machiningView(obj);
        return MblResult.success(obj);
    }

    public void machiningView(T obj) {
    }

    @PostMapping(value = "/removeAll")
    public MblResult removeAll(@RequestParam String ids) {
        this.iService.removeByIds(Arrays.asList(ids.split(",")));
        return MblResult.success();
    }

    @PostMapping(value = "/getAttributes")
    public MblResult getAttributes(){
        final List<UtilClass.TypeAttribute> attributes = UtilClass.getAttributes(this);
        return MblResult.success(attributes);
    }

    /**
     * 获取时间差值
     */
    public Object getTimePoor(LocalDateTime addTime) {
        if (addTime == null) {
            return "";
        }
        Duration duration = Duration.between(addTime, LocalDateTime.now());
        if (duration.toMinutes() < 1) {
            return "刚刚";
        } else if (duration.toMinutes() > 1 && duration.toMinutes() <= 60) {
            return duration.toMinutes() + "分钟前";
        } else if (duration.toHours() >= 1 && duration.toHours() <= 24) {
            return duration.toHours() + "小时前";
        } else if (duration.toDays() >= 1 && duration.toDays() <= 30) {
            return duration.toDays() + "天前";
        } else if (duration.toDays() >= 30 && duration.toDays() <= 365) {
            int i = new Double(Math.floor(duration.toDays() / 30)).intValue();
            return i + "个月前";
        } else {
            int i = new Double(Math.floor(duration.toDays() / 365)).intValue();
            return i + "年前";
        }
    }
}
